/*
 * Copyright 2002-2020 the original author or authors.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      https://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package org.springframework.context.event;

import java.util.ArrayList;
import java.util.Collection;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;

import org.springframework.aop.framework.AopProxyUtils;
import org.springframework.beans.factory.BeanClassLoaderAware;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.BeanFactoryAware;
import org.springframework.beans.factory.NoSuchBeanDefinitionException;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.beans.factory.config.ConfigurableBeanFactory;
import org.springframework.context.ApplicationEvent;
import org.springframework.context.ApplicationListener;
import org.springframework.core.ResolvableType;
import org.springframework.core.annotation.AnnotationAwareOrderComparator;
import org.springframework.lang.Nullable;
import org.springframework.util.Assert;
import org.springframework.util.ClassUtils;
import org.springframework.util.ObjectUtils;

/**
 * Abstract implementation of the {@link ApplicationEventMulticaster} interface,
 * providing the basic listener registration facility.
 *
 * <p>Doesn't permit multiple instances of the same listener by default,
 * as it keeps listeners in a linked Set. The collection class used to hold
 * ApplicationListener objects can be overridden through the "collectionClass"
 * bean property.
 *
 * <p>Implementing ApplicationEventMulticaster's actual {@link #multicastEvent} method
 * is left to subclasses. {@link SimpleApplicationEventMulticaster} simply multicasts
 * all events to all registered listeners, invoking them in the calling thread.
 * Alternative implementations could be more sophisticated in those respects.
 *
 * <p>
 * ========== 双语设计说明（类级别总结/调用链/框架作用/设计模式） ==========
 *
 * 核心功能（Core Responsibility）：
 * - 提供 Spring 事件广播器（ApplicationEventMulticaster）的抽象基类，负责：
 *   1) 维护并管理 ApplicationListener（支持直接注册对象和基于 beanName 的延迟加载）；
 *   2) 提供线程安全的注册/移除/查询操作；
 *   3) 通过按 EventType+SourceType 缓存（retrieverCache）来提高事件分发时的监听器检索性能；
 *   4) 将实际的事件分发（multicastEvent）逻辑留给子类实现（如 SimpleApplicationEventMulticaster），使得广播策略可插拔。
 *
 * 主要逻辑流程（按序，结合关键变量和调用链）：
 * 1. Listener 注册/移除（add/removeApplicationListener, add/removeApplicationListenerBean）：
 *    - 写操作在 defaultRetriever 上加锁，变更 defaultRetriever.applicationListeners 或 applicationListenerBeans；
 *    - 每次写操作都会清空 retrieverCache（cache invalidation），保证后续检索能看到最新监听器集合。
 * 2. 获取监听器（getApplicationListeners(event, eventType)）：
 *    - 基于事件类型（ResolvableType）与事件源类型（source.getClass()）构建 ListenerCacheKey；
 *    - 优先尝试从 retrieverCache 获取已缓存的 CachedListenerRetriever（快速路径）；
 *    - 若缓存缺失且类型可缓存，则创建新的 CachedListenerRetriever 并 putIfAbsent，避免重复创建；
 *    - 若缓存存在但未填充（并发情况下），回退到 retrieveApplicationListeners 全量计算路径；
 *    - retrieveApplicationListeners 会：
 *       a) 从 defaultRetriever（快照）拷贝已注册的对象监听器集合与 beanName 集合；
 *       b) 对对象监听器逐个调用 supportsEvent(listener, eventType, sourceType) 进行过滤；
 *       c) 对 beanName 监听器，先用 supportsEvent(beanFactory, listenerBeanName, eventType) 做早期泛型检查，
 *          以避免不必要的实例化；若匹配则 getBean() 实例化并再次用 supportsEvent(instance, eventType, sourceType) 过滤；
 *       d) 合并结果、按顺序（@Order 或 Ordered）排序，必要时填充 retriever（用于缓存）。
 * 3. 事件分发（由子类实现的 multicastEvent 使用 getApplicationListeners 获取目标监听器）：
 *    - 子类（例如 SimpleApplicationEventMulticaster）会遍历该集合并调用监听器的回调方法，
 *      可以同步执行或通过 TaskExecutor 实现异步分发。
 *
 * 在 Spring 框架中的作用与前后调用关系（Role & Call Sites）：
 * - 作用：负责事件到监听器的路由与匹配，是 Spring 事件发布子系统的核心组件之一。
 * - 前置：事件由 ApplicationContext.publishEvent(...) 发起（事件源为 ApplicationContext）；该方法会委托给 ApplicationEventMulticaster.multicastEvent(...)。
 * - 本类职责：管理监听器集合、提供基于事件类型/源类型的高效检索、缓存与延迟实例化支持；但不直接实现 multicast 的具体分发细节（交由子类）。
 * - 后置：multicastEvent 获取监听器后依次触发监听器的 onApplicationEvent 或通过适配器调用泛型监听方法。
 *
 * 设计模式与架构思想（Patterns & Trade-offs）：
 * - 观察者模式（Observer/Listener）：事件-监听关系的经典实现，优点是松耦合、易扩展；缺点是当监听器过多或事件过频会带来性能压力（需加缓存/限流）。
 * - 策略/可插拔（Strategy + Template）：本类提供通用管理逻辑，具体广播策略由子类实现（比如同步 vs 异步），提高了灵活性。
 * - 缓存+延迟加载（Cache + Lazy Loading）：通过 retrieverCache + beanName 延迟实例化减少反射/实例化开销；优点是性能与内存折中，缺点是缓存失效复杂度（并发填充、正确的 invalidation）。
 * - 适配器（Adapter）：GenericApplicationListenerAdapter 用于将传统 ApplicationListener 适配成支持泛型检测的 GenericApplicationListener。
 * - 并发控制（ConcurrentHashMap + synchronized）：读多写少场景下设计为读优先缓存，写操作清空缓存以保证一致性；优点实现简单、线程安全；缺点是在写频繁时性能下降。
 *
 * 小结（Summary）：
 * - 本类将监听器的注册、早期过滤（避免不必要的 bean 实例化）、按事件类型/源类型缓存与排序等核心管理逻辑抽象出来，
 *   允许子类专注于具体的分发策略（同步/异步/线程池等）。这是 Spring 事件子系统中非常关键且考虑性能的部分。
 *
 * ===================================================================
 *
 * 原始英文注释保留在方法/字段上方，并在必要处添加中文翻译与设计背景说明。
 *
 * @author Juergen Hoeller
 * @author Stephane Nicoll
 * @since 1.2.3
 * @see #getApplicationListeners(ApplicationEvent, ResolvableType)
 * @see SimpleApplicationEventMulticaster
 */
public abstract class AbstractApplicationEventMulticaster
		implements ApplicationEventMulticaster, BeanClassLoaderAware, BeanFactoryAware {

	/** 默认的监听器存储器（线程安全） */
	private final DefaultListenerRetriever defaultRetriever = new DefaultListenerRetriever();

	/** 用于缓存不同事件类型和源类型对应的监听器集合，提升检索效率 */
	final Map<ListenerCacheKey, CachedListenerRetriever> retrieverCache = new ConcurrentHashMap<>(64);

	/** Bean 类加载器，用于反射加载监听器 */
	@Nullable
	private ClassLoader beanClassLoader;

	/** BeanFactory，用于按名称延迟加载监听器 Bean */
	@Nullable
	private ConfigurableBeanFactory beanFactory;


	@Override
	public void setBeanClassLoader(ClassLoader classLoader) {
		this.beanClassLoader = classLoader;
	}

	@Override
	public void setBeanFactory(BeanFactory beanFactory) {
		//如果 beanFactory 不是 ConfigurableBeanFactory 实例
		if (!(beanFactory instanceof ConfigurableBeanFactory)) {
			// 抛出非法状态异常：不在 ConfigurableBeanFactory：beanFactory
			throw new IllegalStateException("Not running in a ConfigurableBeanFactory: " + beanFactory);
		}
		this.beanFactory = (ConfigurableBeanFactory) beanFactory;
		//如果beanClassLoader为null
		if (this.beanClassLoader == null) {
			//获取beanFactory的类加载器以加载Bean类(即使无法使用系统ClassLoader,也只能为null)
			this.beanClassLoader = this.beanFactory.getBeanClassLoader();
		}
	}

	/**
	 * 获取当前BeanFactory
	 * @return
	 */
	private ConfigurableBeanFactory getBeanFactory() {
		//如果beanFactory为null
		if (this.beanFactory == null) {
			throw new IllegalStateException("ApplicationEventMulticaster cannot retrieve listener beans " +
					"because it is not associated with a BeanFactory");
		}
		//返回当前BeanFactory
		return this.beanFactory;
	}


	/**
	 * 添加应用程序监听器类
	 * @param listener the listener to add
	 */
	@Override
	public void addApplicationListener(ApplicationListener<?> listener) {
		//使用defaultRetriever加锁，保证线程安全
		synchronized (this.defaultRetriever) {
			// Explicitly remove target for a proxy, if registered already,
			// in order to avoid double invocations of the same listener.
			// 显式删除代理的目标(如果已经注册)，以避免对同一个监听器的两次调用。
			// 背景说明：当 listener 是 AOP 代理时，既可能注册了代理也可能注册了目标对象，移除目标对象可以避免重复调用。
			Object singletonTarget = AopProxyUtils.getSingletonTarget(listener);
			//如果singletonTarget是ApplicationListener实例
			if (singletonTarget instanceof ApplicationListener) {
				//将singletonTarget从defaultRetriever.applicationListeners中移除
				this.defaultRetriever.applicationListeners.remove(singletonTarget);
			}
			//将listener添加到defaultRetriever.applicationListeners中
			this.defaultRetriever.applicationListeners.add(listener);
			//清空缓存，因为listener可能支持缓存的某些事件类型和源类型，所以要刷新缓存
			this.retrieverCache.clear();
		}
	}

	@Override
	public void addApplicationListenerBean(String listenerBeanName) {
		//使用defaultRetriever加锁，保证线程安全
		synchronized (this.defaultRetriever) {
			this.defaultRetriever.applicationListenerBeans.add(listenerBeanName);
			// 清空缓存，因为 listener 的集合发生变化，需使缓存失效
			this.retrieverCache.clear();
		}
	}

	@Override
	public void removeApplicationListener(ApplicationListener<?> listener) {
		//使用defaultRetriever加锁，保证线程安全
		synchronized (this.defaultRetriever) {
			this.defaultRetriever.applicationListeners.remove(listener);
			//清空缓存，因为 listener 集合变化，需要刷新缓存
			this.retrieverCache.clear();
		}
	}

	@Override
	public void removeApplicationListenerBean(String listenerBeanName) {
		//使用defaultRetriever加锁，保证线程安全
		synchronized (this.defaultRetriever) {
			//将listener从retriever的ApplicationListener对象集合中移除
			this.defaultRetriever.applicationListenerBeans.remove(listenerBeanName);
			//清空缓存，因为listener集合变化，需要刷新缓存
			this.retrieverCache.clear();
		}
	}

	@Override
	public void removeAllListeners() {
		//使用defaultRetriever加锁，保证线程安全
		synchronized (this.defaultRetriever) {
			//清空defaultRetriever的ApplicationListener对象集合
			this.defaultRetriever.applicationListeners.clear();
			//清空defaultRetriever的BeanFactory中的applicationListener类型Bean名集合
			this.defaultRetriever.applicationListenerBeans.clear();
			//清空缓存，因为listener集合变化，需要刷新缓存
			this.retrieverCache.clear();
		}
	}


	/**
	 * Return a Collection containing all ApplicationListeners.
	 * 返回包含所有 ApplicationListener 的集合。
	 *
	 * @return a Collection of ApplicationListeners
	 * @see org.springframework.context.ApplicationListener
	 */
	protected Collection<ApplicationListener<?>> getApplicationListeners() {
		//使用defaultRetriever加锁，保证线程安全
		synchronized (this.defaultRetriever) {
			//返回defaultRetriever的包含所有applicationListener的集合
			return this.defaultRetriever.getApplicationListeners();
		}
	}

	/**
	 * Return a Collection of ApplicationListeners matching the given
	 * event type. Non-matching listeners get excluded early.
	 *
	 * 返回与给定事件类型匹配的 ApplicationListener 集合。
	 * 不匹配的监听器会尽早被排除，从而避免不必要的实例化与调用。
	 *
	 * 方法行为摘要（Summary of behavior）：
	 * - 基于事件类型（ResolvableType）与事件源类型构建缓存 key；
	 * - 优先尝试从 retrieverCache 获取预计算的监听器集合（快速路径）；
	 * - 缓存不存在或未完全填充时，调用 retrieveApplicationListeners 做完整匹配与可选的缓存填充；
	 *
	 * 关键变量：
	 * - event: 事件对象，包含源（source）供进一步过滤；
	 * - eventType: 事件的 ResolvableType，支持泛型事件匹配；
	 * - ListenerCacheKey: 以 (eventType, sourceType) 作为缓存键；
	 * - CachedListenerRetriever: 缓存匹配后的监听器集合（延迟填充以支持并发）。
	 *
	 * 性能与并发要点（Performance/Concurrency notes）：
	 * - 仅在类型被认为“cache-safe”（ClassUtils.isCacheSafe）时才会尝试将检索器放入全局缓存；
	 * - 并发填充缓存时，其他线程会回退到非缓存路径计算（结果正确但代价更高）。
	 *
	 * @param event the event to be propagated. Allows for excluding
	 * non-matching listeners early, based on cached matching information.
	 *              要传播的事件。允许基于缓存信息尽早排除不匹配的监听器。
	 * @param eventType the event type
	 *                  事件的 ResolvableType 类型
	 * @return a Collection of ApplicationListeners
	 *         返回匹配该事件的监听器集合
	 * @see org.springframework.context.ApplicationListener
	 */
	protected Collection<ApplicationListener<?>> getApplicationListeners(
			ApplicationEvent event, ResolvableType eventType) {

		Object source = event.getSource();
		Class<?> sourceType = (source != null ? source.getClass() : null);
		ListenerCacheKey cacheKey = new ListenerCacheKey(eventType, sourceType);

		// Potential new retriever to populate
		// 可能用于填充缓存的新 retriever（延迟初始化）
		CachedListenerRetriever newRetriever = null;

		// Quick check for existing entry on ConcurrentHashMap
		// 在 ConcurrentHashMap 中快速检查是否已有缓存条目
		CachedListenerRetriever existingRetriever = this.retrieverCache.get(cacheKey);
		if (existingRetriever == null) {
			// Caching a new ListenerRetriever if possible
			// 如果条件允许（类型对当前 ClassLoader 是 cache-safe），则创建并尝试放入缓存
			if (this.beanClassLoader == null ||
					(ClassUtils.isCacheSafe(event.getClass(), this.beanClassLoader) &&
							(sourceType == null || ClassUtils.isCacheSafe(sourceType, this.beanClassLoader)))) {
				newRetriever = new CachedListenerRetriever();
				existingRetriever = this.retrieverCache.putIfAbsent(cacheKey, newRetriever);
				if (existingRetriever != null) {
					newRetriever = null;  // no need to populate it in retrieveApplicationListeners
					// 如果其他线程已放入 retriever，则当前线程无需填充它
				}
			}
		}

		if (existingRetriever != null) {
			Collection<ApplicationListener<?>> result = existingRetriever.getApplicationListeners();
			if (result != null) {
				return result;
			}
			// If result is null, the existing retriever is not fully populated yet by another thread.
			// Proceed like caching wasn't possible for this current local attempt.
			// 如果 result 为 null，说明另一个线程正在填充该 retriever；当前线程退回到非缓存路径计算。
		}

		return retrieveApplicationListeners(eventType, sourceType, newRetriever);
	}

	/**
	 * Actually retrieve the application listeners for the given event and source type.
	 * 实际为给定事件/源类型检索应用监听器的实现。
	 *
	 * @param eventType the event type
	 * @param sourceType the event source type
	 * @param retriever the ListenerRetriever, if supposed to populate one (for caching purposes)
	 *                  如果传入 retriever，则此方法应尽可能填充该 retriever 以便缓存。
	 * @return the pre-filtered list of application listeners for the given event and source type
	 */
	private Collection<ApplicationListener<?>> retrieveApplicationListeners(
			ResolvableType eventType, @Nullable Class<?> sourceType, @Nullable CachedListenerRetriever retriever) {

		List<ApplicationListener<?>> allListeners = new ArrayList<>();
		Set<ApplicationListener<?>> filteredListeners = (retriever != null ? new LinkedHashSet<>() : null);
		Set<String> filteredListenerBeans = (retriever != null ? new LinkedHashSet<>() : null);

		Set<ApplicationListener<?>> listeners;
		Set<String> listenerBeans;
		synchronized (this.defaultRetriever) {
			// 从 defaultRetriever 快照一份当前注册的 listener 对象和 listener bean 名称集合（避免长时间锁）
			listeners = new LinkedHashSet<>(this.defaultRetriever.applicationListeners);
			listenerBeans = new LinkedHashSet<>(this.defaultRetriever.applicationListenerBeans);
		}

		// Add programmatically registered listeners, including ones coming
		// from ApplicationListenerDetector (singleton beans and inner beans).
		// 添加通过编程注册的监听器，包括 ApplicationListenerDetector 发现的单例 bean 与内部 bean
		for (ApplicationListener<?> listener : listeners) {
			if (supportsEvent(listener, eventType, sourceType)) {
				if (retriever != null) {
					filteredListeners.add(listener);
				}
				allListeners.add(listener);
			}
		}

		// Add listeners by bean name, potentially overlapping with programmatically
		// registered listeners above - but here potentially with additional metadata.
		// 按 bean 名称添加监听器（可能与上面通过对象注册的重复），但此路径可利用 bean 定义的额外元数据进行更精确的筛选
		if (!listenerBeans.isEmpty()) {
			ConfigurableBeanFactory beanFactory = getBeanFactory();
			for (String listenerBeanName : listenerBeans) {
				try {
					if (supportsEvent(beanFactory, listenerBeanName, eventType)) {
						// 早期泛型/元数据检查通过，开始实例化 bean
						ApplicationListener<?> listener =
								beanFactory.getBean(listenerBeanName, ApplicationListener.class);
						// 确保不重复添加，且实例也支持该事件（再次检查 sourceType）
						if (!allListeners.contains(listener) && supportsEvent(listener, eventType, sourceType)) {
							if (retriever != null) {
								if (beanFactory.isSingleton(listenerBeanName)) {
									// 对于单例 bean，可以直接把实例加入缓存集合
									filteredListeners.add(listener);
								}
								else {
									// 对于原型/非单例，缓存只保存 beanName，避免直接缓存非单例实例
									filteredListenerBeans.add(listenerBeanName);
								}
							}
							allListeners.add(listener);
						}
					}
					else {
						// Remove non-matching listeners that originally came from
						// ApplicationListenerDetector, possibly ruled out by additional
						// BeanDefinition metadata (e.g. factory method generics) above.
						// 如果不匹配，从候选中移除（可能之前被探测器添加）
						Object listener = beanFactory.getSingleton(listenerBeanName);
						if (retriever != null) {
							filteredListeners.remove(listener);
						}
						allListeners.remove(listener);
					}
				}
				catch (NoSuchBeanDefinitionException ex) {
					// Singleton listener instance (without backing bean definition) disappeared -
					// probably in the middle of the destruction phase
					// 如果在容器销毁或变更过程中找不到 bean 定义，忽略该异常。
				}
			}
		}

		// 按注解/接口顺序（@Order / Ordered）对监听器排序
		AnnotationAwareOrderComparator.sort(allListeners);
		if (retriever != null) {
			// 如果没有非单例 bean 名称需要单独缓存，则直接把最终实例集合缓存起来
			if (filteredListenerBeans.isEmpty()) {
				retriever.applicationListeners = new LinkedHashSet<>(allListeners);
				retriever.applicationListenerBeans = filteredListenerBeans;
			}
			else {
				// 否则缓存过滤后的实例集合与非单例 beanName 集合
				retriever.applicationListeners = filteredListeners;
				retriever.applicationListenerBeans = filteredListenerBeans;
			}
		}
		return allListeners;
	}

	/**
	 * Filter a bean-defined listener early through checking its generically declared
	 * event type before trying to instantiate it.
	 *
	 * 在尝试实例化 bean 之前，通过检查其在 BeanDefinition 或类上声明的泛型事件类型来尽早过滤掉不匹配的监听器。
	 *
	 * <p>If this method returns {@code true} for a given listener as a first pass,
	 * the listener instance will get retrieved and fully evaluated through a
	 * {@link #supportsEvent(ApplicationListener, ResolvableType, Class)} call afterwards.
	 *
	 * 如果此方法对某个 listener 返回 true，则会进一步实例化该 listener，并通过 supportsEvent(ApplicationListener, ...) 完成最终检查。
	 *
	 * @param beanFactory the BeanFactory that contains the listener beans
	 * @param listenerBeanName the name of the bean in the BeanFactory
	 * @param eventType the event type to check
	 * @return whether the given listener should be included in the candidates
	 * for the given event type
	 * @see #supportsEvent(Class, ResolvableType)
	 * @see #supportsEvent(ApplicationListener, ResolvableType, Class)
	 */
	private boolean supportsEvent(
			ConfigurableBeanFactory beanFactory, String listenerBeanName, ResolvableType eventType) {

		Class<?> listenerType = beanFactory.getType(listenerBeanName);
		if (listenerType == null || GenericApplicationListener.class.isAssignableFrom(listenerType) ||
				SmartApplicationListener.class.isAssignableFrom(listenerType)) {
			// 如果无法确定类型或已经是更智能的 listener 接口实现，则保守地返回 true（避免误排除）
			return true;
		}
		if (!supportsEvent(listenerType, eventType)) {
			// 如果按类的声明泛型已经不支持该事件，则直接排除
			return false;
		}
		try {
			BeanDefinition bd = beanFactory.getMergedBeanDefinition(listenerBeanName);
			ResolvableType genericEventType = bd.getResolvableType().as(ApplicationListener.class).getGeneric();
			// 如果 BeanDefinition 中声明了泛型事件类型，确保其能够兼容当前事件
			return (genericEventType == ResolvableType.NONE || genericEventType.isAssignableFrom(eventType));
		}
		catch (NoSuchBeanDefinitionException ex) {
			// Ignore - no need to check resolvable type for manually registered singleton
			// 忽略 - 手动注册的单例可能没有 BeanDefinition，不需要进一步检查
			return true;
		}
	}

	/**
	 * 通过解析 listenerType 上声明的泛型事件类型来提前过滤监听器（用于快速判断）。
	 *
	 * Filter a listener early through checking its generically declared event
	 * type before trying to instantiate it.
	 * <p>If this method returns {@code true} for a given listener as a first pass,
	 * the listener instance will get retrieved and fully evaluated through a
	 * {@link #supportsEvent(ApplicationListener, ResolvableType, Class)} call afterwards.
	 * @param listenerType the listener's type as determined by the BeanFactory
	 * @param eventType the event type to check
	 * @return whether the given listener should be included in the candidates
	 * for the given event type
	 */
	protected boolean supportsEvent(Class<?> listenerType, ResolvableType eventType) {
		ResolvableType declaredEventType = GenericApplicationListenerAdapter.resolveDeclaredEventType(listenerType);
		// 如果无法解析出声明的事件类型（非泛型或不明确），则保守地返回 true
		return (declaredEventType == null || declaredEventType.isAssignableFrom(eventType));
	}

	/**
	 * Determine whether the given listener supports the given event.
	 *
	 * 判断给定 listener 是否支持指定的事件类型与事件源类型。
	 *
	 * <p>The default implementation detects the {@link SmartApplicationListener}
	 * and {@link GenericApplicationListener} interfaces. In case of a standard
	 * {@link ApplicationListener}, a {@link GenericApplicationListenerAdapter}
	 * will be used to introspect the generically declared type of the target listener.
	 *
	 * 默认实现会探测 SmartApplicationListener 与 GenericApplicationListener 接口。
	 * 对于普通的 ApplicationListener，会使用 GenericApplicationListenerAdapter 适配器来检查其泛型声明。
	 *
	 * @param listener the target listener to check
	 * @param eventType the event type to check against
	 * @param sourceType the source type to check against
	 * @return whether the given listener should be included in the candidates
	 * for the given event type
	 */
	protected boolean supportsEvent(
			ApplicationListener<?> listener, ResolvableType eventType, @Nullable Class<?> sourceType) {

		GenericApplicationListener smartListener = (listener instanceof GenericApplicationListener ?
				(GenericApplicationListener) listener : new GenericApplicationListenerAdapter(listener));
		// 支持事件类型并且支持事件源类型则认为该 listener 匹配
		return (smartListener.supportsEventType(eventType) && smartListener.supportsSourceType(sourceType));
	}


	/**
	 * Cache key for ListenerRetrievers, based on event type and source type.
	 * ListenerRetriever 的缓存 key，基于事件类型与源类型。
	 */
	private static final class ListenerCacheKey implements Comparable<ListenerCacheKey> {

		private final ResolvableType eventType;

		@Nullable
		private final Class<?> sourceType;

		public ListenerCacheKey(ResolvableType eventType, @Nullable Class<?> sourceType) {
			Assert.notNull(eventType, "Event type must not be null");
			this.eventType = eventType;
			this.sourceType = sourceType;
		}

		@Override
		public boolean equals(@Nullable Object other) {
			if (this == other) {
				return true;
			}
			if (!(other instanceof ListenerCacheKey)) {
				return false;
			}
			ListenerCacheKey otherKey = (ListenerCacheKey) other;
			return (this.eventType.equals(otherKey.eventType) &&
					ObjectUtils.nullSafeEquals(this.sourceType, otherKey.sourceType));
		}

		@Override
		public int hashCode() {
			return this.eventType.hashCode() * 29 + ObjectUtils.nullSafeHashCode(this.sourceType);
		}

		@Override
		public String toString() {
			return "ListenerCacheKey [eventType = " + this.eventType + ", sourceType = " + this.sourceType + "]";
		}

		@Override
		public int compareTo(ListenerCacheKey other) {
			int result = this.eventType.toString().compareTo(other.eventType.toString());
			if (result == 0) {
				if (this.sourceType == null) {
					return (other.sourceType == null ? 0 : -1);
				}
				if (other.sourceType == null) {
					return 1;
				}
				result = this.sourceType.getName().compareTo(other.sourceType.getName());
			}
			return result;
		}
	}


	/**
	 * Helper class that encapsulates a specific set of target listeners,
	 * allowing for efficient retrieval of pre-filtered listeners.
	 *
	 * 一个辅助类，封装特定事件类型 + 源类型下的目标监听器集合，支持高效检索预过滤好的监听器。
	 * <p>An instance of this helper gets cached per event type and source type.
	 * 每个事件类型与源类型对应一个该 helper 的实例，并被缓存以复用匹配结果。
	 */
	private class CachedListenerRetriever {

		@Nullable
		public volatile Set<ApplicationListener<?>> applicationListeners;

		@Nullable
		public volatile Set<String> applicationListenerBeans;

		@Nullable
		public Collection<ApplicationListener<?>> getApplicationListeners() {
			Set<ApplicationListener<?>> applicationListeners = this.applicationListeners;
			Set<String> applicationListenerBeans = this.applicationListenerBeans;
			if (applicationListeners == null || applicationListenerBeans == null) {
				// Not fully populated yet
				// 尚未被另一个线程完全填充，返回 null 表示缓存尚不可用
				return null;
			}

			List<ApplicationListener<?>> allListeners = new ArrayList<>(
					applicationListeners.size() + applicationListenerBeans.size());
			allListeners.addAll(applicationListeners);
			if (!applicationListenerBeans.isEmpty()) {
				BeanFactory beanFactory = getBeanFactory();
				for (String listenerBeanName : applicationListenerBeans) {
					try {
						allListeners.add(beanFactory.getBean(listenerBeanName, ApplicationListener.class));
					}
					catch (NoSuchBeanDefinitionException ex) {
						// Singleton listener instance (without backing bean definition) disappeared -
						// probably in the middle of the destruction phase
						// 单例 listener 实例（没有对应 BeanDefinition）可能在容器销毁阶段消失，忽略。
					}
				}
			}
			if (!applicationListenerBeans.isEmpty()) {
				AnnotationAwareOrderComparator.sort(allListeners);
			}
			return allListeners;
		}
	}


	/**
	 * Helper class that encapsulates a general set of target listeners.
	 *
	 * 封装一个通用的目标监听器集合（程序注册 + beanName 注册）
	 */
	private class DefaultListenerRetriever {

		public final Set<ApplicationListener<?>> applicationListeners = new LinkedHashSet<>();

		public final Set<String> applicationListenerBeans = new LinkedHashSet<>();

		public Collection<ApplicationListener<?>> getApplicationListeners() {
			List<ApplicationListener<?>> allListeners = new ArrayList<>(
					this.applicationListeners.size() + this.applicationListenerBeans.size());
			allListeners.addAll(this.applicationListeners);
			if (!this.applicationListenerBeans.isEmpty()) {
				BeanFactory beanFactory = getBeanFactory();
				for (String listenerBeanName : this.applicationListenerBeans) {
					try {
						ApplicationListener<?> listener =
								beanFactory.getBean(listenerBeanName, ApplicationListener.class);
						if (!allListeners.contains(listener)) {
							allListeners.add(listener);
						}
					}
					catch (NoSuchBeanDefinitionException ex) {
						// Singleton listener instance (without backing bean definition) disappeared -
						// probably in the middle of the destruction phase
						// 单例 listener 实例可能在容器销毁阶段被移除，忽略该异常。
					}
				}
			}
			AnnotationAwareOrderComparator.sort(allListeners);
			return allListeners;
		}
	}

}
